package com.file.parser;

import com.file.bo.AppAlipayHuaBei;
import com.file.bo.AppAlipayIdCard;
import com.file.bo.AppAlipayPersonal;
import com.file.bo.ResponseData;
import com.file.constant.ErrorCode;
import com.file.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 支付宝花呗xml解析
 * @author anyspa
 */


@Slf4j
public class AppAlipayHuaBeiXmlParser extends AppAlipayBaseXmlParser {

    public ResponseData<String> parseAppAlipayHuaBeiXmlToJson(String daId, String filePath, List<String> huabeiNoDataScenarioList) {
        log.info("parseAppAlipayHuaBeiXmlToJson started, daId:{}, filePath:{}", daId, filePath);
        String json;

        try {
            if (filePath.contains("alipay_huabei") || filePath.contains("alipay_quota-huabei")) {
                AppAlipayHuaBei appAlipayHuaBei = parseAppAlipayHuaBeiXml(daId, filePath, huabeiNoDataScenarioList);
                json = JsonUtils.convertObjectToJson(appAlipayHuaBei);
            } else if (filePath.contains("alipay_personal")) {
                AppAlipayPersonal appAlipayPersonal = parseAppAlipayPersonalXml(filePath);
                json = JsonUtils.convertObjectToJson(appAlipayPersonal);
            } else if (filePath.contains("alipay_idcard")) {
                AppAlipayIdCard appAlipayIdCard = parseAppAlipayIdcardXml(filePath);
                json = JsonUtils.convertObjectToJson(appAlipayIdCard);
            } else {
                throw new RuntimeException("the file name is not supported");
            }
        } catch (Exception e) {
            log.error("|{}||{}|{}|{}|{}", ErrorCode.FILE_PARSE_EXCEPTION.getCode(), daId, "", "", "parseAppAlipayHuaBeiXmlToJson failed", e);
            return new ResponseData<>(null, ErrorCode.FILE_PARSE_EXCEPTION.getCode(),
                    ErrorCode.FILE_PARSE_EXCEPTION.getMsg());
        }

        log.info("parseAppAlipayHuaBeiXmlToJson completed, daId:{}, filePath:{}", daId, filePath);
        return new ResponseData<>(json, ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    private AppAlipayHuaBei parseAppAlipayHuaBeiXml(String daId, String filePath, List<String> huabeiNoDataScenarioList) throws DocumentException {
        AppAlipayHuaBei appAlipayHuaBei = null;
        List<String> nodeTextList = getNodeTextList(filePath);
        String huabeiNoDataKeyword = getNoDataKeyWord(nodeTextList, huabeiNoDataScenarioList);

        //有数据的正常页面，走正常设值逻辑
        if (isNormalCase(nodeTextList)) {
            appAlipayHuaBei = processNormalCase(nodeTextList);
            //命中无数据关键字配置，走无数据设值逻辑
        } else if (StringUtils.isNotBlank(huabeiNoDataKeyword)) {
            appAlipayHuaBei = processNoDataCase(huabeiNoDataKeyword);
            //有数据的逾期案例，走逾期设值逻辑
        } else if (isOverdue(nodeTextList)) {
            appAlipayHuaBei = processOverDueCase(nodeTextList);
            //一些非正常页面，将已知case逐个在这里适配
        } else {
            throw new RuntimeException("Huabei xml meet new case");
        }

        return appAlipayHuaBei;
    }

    private AppAlipayHuaBei processOverDueCase(List<String> nodeTextList) {
        AppAlipayHuaBei appAlipayHuaBei = new AppAlipayHuaBei();
        appAlipayHuaBei.setCaseDesc(getOverdueText(nodeTextList));
        return appAlipayHuaBei;
    }

    private AppAlipayHuaBei processNormalCase(List<String> nodeTextList) {
        AppAlipayHuaBei appAlipayHuaBei = new AppAlipayHuaBei();
        List<AppAlipayHuaBei.Quota> quotaList = new ArrayList<>();
        AppAlipayHuaBei.Quota creditPurchaseQuota = null;
        AppAlipayHuaBei.Quota huaBeiQuota = null;

        // XX信用购额度
        boolean isExistCreditPurchaseAmount = false;
        // 花呗额度
        boolean isArrivedHuaBeiAmount = false;

        // 解析可借额度
        for (String nodeText : nodeTextList) {
            if (!isExistCreditPurchaseAmount && nodeText.contains("信用购额度")) {
                creditPurchaseQuota = new AppAlipayHuaBei.Quota();
                isExistCreditPurchaseAmount = true;
                creditPurchaseQuota.setQuotaType(nodeText.trim());
                continue;
            }
            if (!isArrivedHuaBeiAmount && nodeText.contains("花呗额度")) {
                huaBeiQuota = new AppAlipayHuaBei.Quota();
                isArrivedHuaBeiAmount = true;
                huaBeiQuota.setQuotaType(nodeText.trim());
                continue;
            }

            // xml解析从上到下顺序：可用额度 -> 总计额度 -> XX信用购额度(如果有的话) -> 花呗额度 -> 额度券
            if (!isExistCreditPurchaseAmount) {
                Pattern pattern = Pattern.compile("(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))|--");
                Matcher matcher = pattern.matcher(nodeText.trim());
                if (matcher.find() && StringUtils.isBlank(appAlipayHuaBei.getAvailableAmount())) {
                    appAlipayHuaBei.setAvailableAmount(matcher.group());
                    continue;
                }

                Pattern pattern2 = Pattern.compile("(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))|--");
                Matcher matcher2 = pattern2.matcher(nodeText.trim());
                if (matcher2.find() && StringUtils.isBlank(appAlipayHuaBei.getTotalAmount())) {
                    appAlipayHuaBei.setTotalAmount(matcher2.group());
                }
            }
            // XX信用购额度
            else {
                if (!isArrivedHuaBeiAmount) {
                    Pattern pattern = Pattern.compile("(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))");
                    Matcher matcher = pattern.matcher(nodeText.trim());
                    if (matcher.find() && StringUtils.isBlank(creditPurchaseQuota.getTotalAmount())) {
                        creditPurchaseQuota.setTotalAmount(matcher.group().trim());
                        continue;
                    }

                    Pattern pattern2 = Pattern.compile("(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))");
                    Matcher matcher2 = pattern2.matcher(nodeText.trim());
                    if (matcher2.find() && StringUtils.isBlank(creditPurchaseQuota.getAvailableAmount())) {
                        creditPurchaseQuota.setAvailableAmount(matcher2.group().trim());
                    }
                } else {
                    // 花呗额度 介于 XX信用购额度 和 额度券 之间
                    if (StringUtils.equalsAny(nodeText.trim(), "额度券", "额度工具")) {
                        break;
                    }
                    Pattern pattern = Pattern.compile("(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))");
                    Matcher matcher = pattern.matcher(nodeText.trim());
                    if (matcher.find() && StringUtils.isBlank(huaBeiQuota.getTotalAmount())) {
                        huaBeiQuota.setTotalAmount(matcher.group().trim());
                        continue;
                    }

                    Pattern pattern2 = Pattern.compile("(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))");
                    Matcher matcher2 = pattern2.matcher(nodeText.trim());
                    if (matcher2.find() && StringUtils.isBlank(huaBeiQuota.getAvailableAmount())) {
                        huaBeiQuota.setAvailableAmount(matcher2.group().trim());
                    }
                }
            }
        }
        if (Objects.nonNull(creditPurchaseQuota) && StringUtils.isNoneBlank(creditPurchaseQuota.getQuotaType(), creditPurchaseQuota.getTotalAmount())) {
            if (StringUtils.isBlank(creditPurchaseQuota.getAvailableAmount())) {
                creditPurchaseQuota.setAvailableAmount("");
            }
            quotaList.add(creditPurchaseQuota);
        }
        if (Objects.nonNull(huaBeiQuota) && StringUtils.isNoneBlank(huaBeiQuota.getQuotaType(), huaBeiQuota.getTotalAmount())) {
            if (StringUtils.isBlank(huaBeiQuota.getAvailableAmount())) {
                huaBeiQuota.setAvailableAmount("");
            }
            quotaList.add(huaBeiQuota);
        }

        if (!quotaList.isEmpty()) {
            appAlipayHuaBei.setCaseDesc(JsonUtils.convertObjectToJson(quotaList));
        }

        return appAlipayHuaBei;
    }

    private AppAlipayHuaBei processNoDataCase(String huabeiNoDataKeyword) {
        AppAlipayHuaBei appAlipayHuaBei = new AppAlipayHuaBei();
        appAlipayHuaBei.setCaseDesc(huabeiNoDataKeyword);
        return appAlipayHuaBei;
    }

    private String getOverdueText(List<String> nodeTextList) {
        for (String nodeText : nodeTextList) {
            if (nodeText.contains("逾期")) {
                return nodeText;
            }
        }
        return null;
    }

    private boolean isOverdue(List<String> nodeTextList) {
        boolean isOverDue = false;

        for (String nodeText : nodeTextList) {
            if (nodeText.contains("逾期")) {
                isOverDue = true;
                break;
            }
        }
        return isOverDue;
    }

    //xml原文件同时包含可用额度和总计额度视为正常case
    private boolean isNormalCase(List<String> nodeTextList) {
        boolean hasAvailableAmount = false;
        boolean hasTotalAmount = false;


        for (String nodeText : nodeTextList) {
            if (nodeText.contains("可用额度") || nodeText.contains("预计可用(元)")) {
                hasAvailableAmount = true;
            }
            if (nodeText.contains("总计额度")) {
                hasTotalAmount = true;
            }
        }
        return hasAvailableAmount && hasTotalAmount;
    }

    public static void main(String[] args) {
        AppAlipayHuaBeiXmlParser appAlipayHuaBeiXmlParser = new AppAlipayHuaBeiXmlParser();
        List<String> huabeiNoDataScenarioList = Arrays.asList("花呗暂时无法为您服务", "不支持开通花呗", "你暂时无法升级");
        String json = appAlipayHuaBeiXmlParser.parseAppAlipayHuaBeiXmlToJson("", "C:\\Users\\lingfeng\\Downloads\\zd2qrnk81791399044102787072_575252a901f94f545695167d887afb3e_alipay_huabei.xml", huabeiNoDataScenarioList).getData();
        System.out.println(json);
    }
}